home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
nan_news
/
vol2
/
no2
/
bmouse.asm
next >
Wrap
Assembly Source File
|
1987-12-08
|
16KB
|
440 lines
;*******************************************
;* Filename..............:BMOUSE.asm
;*------------------------------------------
;* PART I - Adapted from.: PC Magazine, Vol.6 No.13; July 21,1987
;* Article: MOUSE SOFTWARE by Jeff Prosise
;* Modified by...........: Bao Hoang
;* Date..................: August 1987
;*
;* Syntax.......: memvar = M_SET_ON()
;* : memvar = M_SET_OFF()
;*
;* Return values: M_SET_ON() - .T. if everything is O.K. and .F.
;* if something is wrong (i.e.,
;* mouse driver not installed)
;* M_SET_OFF() - always returns .T. and return
;* value can pretty much be ignored
;*
;* CSR_ON() - .T. if everything is O.K. and .F.
;* if it was not able to install the
;* routine (i.e., mouse driver not
;* installed)
;*
;* CSR_OFF() - always returns a .T.
;*
;*******************************************
;*** declare callable routines as PUBLIC
;
public M_SET_ON
public M_SET_OFF
public CSR_ON
public CSR_OFF
public LD_SCR
;*** declare Clipper's procedures for returning variables as FAR
;
extrn __RETL:far ; returns logical type
extrn __PARNI:far
;*** define keys to insert based on mouse conditions.
;
LB equ 1C0Dh ; set LEFT button to RETURN key
CB equ 3B00h ; set CENTER button to F1 key
RB equ 011Bh ; set RIGHT button to ESC key
;*** Define keyboard buffer area.
;
BIOS_DATA segment at 40h
org 1ah
BUFFER_HEAD dw ? ;pointer to the keybord
;buffer head
BUFFER_TAIL dw ? ;pointer to the keyboard
;buffer tail
org 80h
BUFFER_START dw ? ;starting keyboard buffer address
BUFFER_END dw ? ;ending keyboard buffer address
BIOS_DATA ends
;
;
;
CODE segment 'CODE' ; declare code segment of class CODE
assume cs:CODE,ds:BIOS_DATA
VCOUNT db 10 ; vertical delay counter
HCOUNT db 10 ; horizontal delay counter
HFLAG dw ? ; horizontal count sign flag
VFLAG dw ? ; vertical count sign flag
KEYCODE db 4Dh,4Bh,50h,48h ;keycodes for cursor keys
EIGHTY db 80 ; to allow multiply by 80
SV_AX dw ? ; temporary storage of AX register
SV_DX dw ? ; temporary storage of DX register
SCR_MAP db 2000 dup (0) ;screen map 80x25
SCR_OFF dw 0 ; screen offset
P_LEN dw 0 ; prompt length
FILL_CHAR db 0 ; character to fill are with
;=========================================
;= PART I:
;=
;= MOUSE, M_SET_ON(), M_SET_OFF()
;=
;= Used for the "keyboard emulation" mouse. These are the mouse
;= routines used to make the highlighting bar (w/ @...prompt/menu
;= to) move when you move the mouse.
;=========================================
;
MOUSE proc far
;
; determine which event occured, and branch accordingly
;
test ax,2 ; left button pressed?
jnz LEFT ; if yes, then go insert 'LB' into buffer
test ax,8 ; right button pressed?
jnz RIGHT ; if yes, then go insert 'RB' into buffer
test ax,32 ; center button pressed? (PC MOUSE)
jnz CENTER ; if yes, then go insert 'CB' into buffer
MOUSE0:
mov ax,11 ; use mouse driver's function 11
int 51 ; read mouse motion counters
mov HFLAG,0 ; initialize sign flags
mov VFLAG,2 ;
xor al,al ; zero AL for extended keycode
cmp cx,0 ; horizontal count positive?
jge MOUSE1 ; yes, then branch
inc HFLAG ; record negative condition
neg cx ; convert negative to positive
MOUSE1:
cmp dx,0 ; vertical count positive
jge MOUSE2 ; yes, then branch
inc VFLAG ; record negative condition
neg dx ; convert negative to positive
MOUSE2:
mov bx,HFLAG ; assume motion was horizontal
cmp cx,dx ; was assumption correct?
jae HORIZ ; yes, then branch
mov bx,VFLAG ; no, then correct it
dec VCOUNT ; decrement vertical delay count
jz MOUSE3 ; continue if count is zero
jmp GET_OUT
HORIZ:
dec HCOUNT
jz MOUSE3
GET_OUT:
ret
MOUSE3:
mov HCOUNT,10
mov VCOUNT,10 ; reset delay counter
mov ah,KEYCODE[bx] ; get keycode from table
call INSERT ; insert it into keyboard buffer
jmp RETURN
LEFT:
mov ax,LB ; load pre-defined 'LB' keycode
; into buffer
call INSERT ; insert it into buffer
jmp RETURN
RIGHT:
mov ax,RB ; load pre-defined 'RB' keycode
; into buffer
call INSERT ; insert it into buffer
jmp RETURN
CENTER:
mov ax,CB ; load pre-defined 'CB' keycode
; into buffer
call INSERT ; insert it into buffer
RETURN:
ret
MOUSE endp
;
;
;
;****************************************
;** M_SET_ON() : routine to set up a function to be called upon
;** mouse activity, using the mouse driver's
;** function 12.
;****************************************
M_SET_ON proc far
push bp ; save everything as documented in
mov bp,sp ; Aut '86 Nantucket News or you
push ds ; will blow up!
push es ;
mov ax,0 ; use function 0 of driver to see
int 33h ; if mouse and driver are installed
or ax,ax ; is there a mouse?
jne OK ; yes, continue
mov bx,0 ; return to Clipper a .F. to tell
push bx ; it that M_SET_ON() failed to set
call __retl ; up the routine (extended interface)
jmp DONE ; go back to Clipper
OK:
mov ax,15 ; use function 15 of mouse driver to
mov cx,400 ; set the mouses sensitivity
mov dx,800 ;
int 33h ;
mov ax,seg MOUSE ; tell function 12 where to find the
mov es,ax ; the mouse routine
mov dx,offset MOUSE ;
mov ax,12 ; use function 12
mov cx,0000000000101011b ; set up the mask for buttons
; and cursor
int 33h ; set it up!
mov bx,1 ; return a .T. to Clipper to tell it
push bx ; that the installation was successful
call __retl ; (using Clipper's extended interface)
DONE:
pop bx ; restore the stack or DIE!!!!
pop es ;
pop ds ;
pop bp ;
ret ; exit and pray!!
M_SET_ON endp
;
;
;
;***********************************************
;** M_SET_OFF() : routine to disable the mouse routine so that
;** accidentally hitting the mouse won't cause the
;** cursor keys to be inserted into the keyboard
;** buffer
;***********************************************
M_SET_OFF proc far
push bp ; save these registers as usual
mov bp,sp ;
push ds ; or DIE!!!!!
push es ;
mov ax,0 ; use function 0 of the mouse driver
int 33h ; to reset the mouse settings which
mov bx,1 ; effectively turns off the mouse routine
push bx ; return a .T. which really has no
call __retl ; meaning but needs to be done to allow
pop bx ; the routine to be used as a UDF without
pop es ; hanging. Restore the stack or hang
pop ds ; like a
pop bp ; bleep, bleep !!!!
ret ;
M_SET_OFF endp
;=====================================================
;= PART II:
;=
;= CSR_ON(),CSR_OFF(),MOUSER
;=
;= Routines used to simulate a "free floating" mouse cursor
;= (Mac-like).
;=====================================================
;
;
;*****************************************************
;* CSR_ON() - Sets the mouse cursor on.
;*****************************************************
CSR_ON proc far
push bp ; save everything as documented in
mov bp,sp ; Aut '86 Nantucket News or you
push ds ; will blow up!
push es ;
mov ax,0 ; use function 0 of driver to see
int 33h ; if mouse and driver are installed
or ax,ax ; is there a mouse?
jne OK2 ; yes, continue
mov bx,0 ; return to Clipper a .F. to tell
push bx ; it that CSR_ON() failed to turn
call __retl ; on the mouse cursor
jmp DONE2 ; go back to Clipper
OK2: mov ax,1 ; use function 1 of mouse driver
int 33h ; to turn cursor on
mov ax,seg MOUSER ; tell function 12 where to
mov es,ax ; find the mouse routine
mov dx,offset MOUSER ;
mov ax,12 ; use function 12
mov cx,0000000000101010b; set up the mask for buttons
; and cursor
int 33h ; set it up!
mov bx,1 ; return a .T. to Clipper to tell it
push bx ; that the installation was successful
call __retl ; (using Clipper's extended interface)
DONE2:
pop bx ; restore the stack or DIE!!!!
pop es ;
pop ds ;
pop bp ;
ret ; exit and pray!!
CSR_ON endp
;
;
;*****************************************************
;* CSR_OFF() - Sets the mouse cursor off.
;*****************************************************
CSR_OFF proc far
push bp ; save everything as documented in
mov bp,sp ; Aut '86 Nantucket News or you
push ds ; will blow up!
push es ;
OK3: mov ax,2 ; use function 2 of mouse driver
int 33h ; to turn cursor off
mov ax,0 ; use function 0 to
int 33h ; reset mouse...
mov bx,1 ; return a .T. to Clipper to tell it
push bx ; that the un-installation was successful
call __retl ; (using Clipper's extended interface)
DONE3:
pop bx ; restore the stack or DIE!!!!
pop es ;
pop ds ;
pop bp ;
ret ; exit and pray!!
CSR_OFF endp
;
;
;*********************************************************
;* MOUSER - Resident mouse routine for "free form mouse"
;*********************************************************
MOUSER proc far
mov ax,3 ; use function 3 of
int 33h ; mouse interrupt to determine
mov ax,cx ; store horiz. position in ax
xor ch,ch ;
mov cl,3 ;
sar ax,cl ; divide horiz. pos. by 8
sar dx,cl ; divide vert. pos by 8
mov SV_AX,ax ; save ax
mov SV_DX,dx ; save dx
mov ax,dx ;
call MULT10 ; multiply vert. count by 80
mov cl,3 ;
shl ax,cl ;
add ax,SV_AX ; then add horiz. pos.
mov bx,ax ;
int 3h
cmp SCR_MAP[bx],0 ; check to see if we are supposed to
; hit return
je DO_NADA ; don't do nothin' if it's 0
mov al,SCR_MAP[bx] ;
xor ah,ah
call INSERT
DO_NADA:
ret
MOUSER endp
;
;
;
;*****************************************************************
;* LD_SCR() - load the SCR_MAP with the appropriate values (called
;* from Clipper)
;*****************************************************************
LD_SCR proc far
push bp ; save stack or DIE !!
mov bp,sp
push ds
push es
mov ax,1 ; get first parameter (SCR_OFF)
push ax ;
call __parni ;
mov SCR_OFF,ax ;
pop ax
mov ax,2 ; get second parameter (P_LEN)
push ax ;
call __parni ;
mov P_LEN,ax ;
pop ax
mov ax,3 ; get third parameter (ASC(<expC>))
push ax ;
call __parni ;
mov SV_AX,ax ;
pop ax
mov ax,SV_AX
xor ah,ah
mov cx,P_LEN ; fill SCR_MAP with appropriate
mov bx,SCR_OFF ; characters
NEXT:mov SCR_MAP[bx],al ;
inc bx ;
loop next ;
pop es ; restore stack or DIE !!
pop ds ;
pop bp ;
ret
LD_SCR endp
;
;
;=========================================================
;= Utility routines....... =
;=========================================================
;
;*********************************************************
;* INSERT - procedure to insert keys into keyboard buffer
;*********************************************************
INSERT proc near
mov bx,BIOS_DATA ; point DS to the BIOS data area
mov ds,bx ;
assume ds:BIOS_DATA ;
cli ; disable interrupts
mov bx,BUFFER_TAIL ; get buffer tail address
mov dx,bx ; transfer it to DX
add dx,2 ; calculate next buffer position
cmp dx,BUFFER_END ; did we overshoot the end?
jne INSERT1 ; no, then continue
mov dx,BUFFER_START ; yes, then wrap to start
; of buffer
INSERT1:
cmp cx,BUFFER_HEAD ; is the buffer full?
je INSERT2 ; yes, then end now
mov [bx],ax ; insert the keycode
mov bx,dx ; advance the tail
mov BUFFER_TAIL,bx ; record its new position
INSERT2:
sti ; enable interrupts
assume ds:nothing ;
ret ; exit user sub-routine
INSERT endp
;
;
;
;****************************************************************
;* MULT10 - multiply by ten
;****************************************************************
MULT10 proc near
shl ax,1
mov cx,ax
shl ax,1
shl ax,1
add ax,cx
ret
MULT10 endp
CODE ends
end